#include "udp_server.h"

Udp_server::Udp_server()
{

}

Udp_server::~Udp_server()
{
    close(this->sockfd);
}

void Udp_server::Init(const char* argv[])
{
    struct sockaddr_in serveraddr;
    this->sockfd = -1;
    this->addrlen = sizeof(struct sockaddr_in);
    memset(&this->clientaddr, 0, this->addrlen);
    memset(&serveraddr, 0, this->addrlen);

    this->sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(this->sockfd == -1)
    {
        ERROR("socket error");
    }

    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[2]);
    serveraddr.sin_port = htons(atoi(argv[3]));

    if(bind(this->sockfd, (struct sockaddr *)&serveraddr, this->addrlen) == -1)
    {
        ERROR("bind error");
    }
}

void Udp_server::recv_clientaddr()
{
    char buffer[1];
    if(recvfrom(this->sockfd, buffer, sizeof(buffer), MSG_PEEK, (struct sockaddr*)&this->clientaddr, &this->addrlen) == -1)
    {   
        ERROR("recvfrom error");
    }
    Print_GREEN("Client:[%s %d] Sink!", inet_ntoa((this->clientaddr).sin_addr), ntohs((this->clientaddr).sin_port));
}

void Udp_server::send_rgb_data(VideoDevice *ptVideoDevice)
{
#if 1
    int data_size = ptVideoDevice->iWidth * ptVideoDevice->iHeight * 3;  // 24位RGB数据
    int packet_size = 4096;  // 单个数据包的大小
    int total_packets = (data_size + packet_size - 1) / packet_size;

    for (int i = 0; i < total_packets; i++) {
        int offset = i * packet_size;
        int bytes_to_send = std::min(packet_size, data_size - offset);

        if(sendto(this->sockfd, ptVideoDevice->rgb_data[ptVideoDevice->iVideoBufCurIndex] + offset, bytes_to_send, 0, (struct sockaddr *)&this->clientaddr, this->addrlen) == -1)
        {
            ERROR("sendto error");
        }
    }
#else
    int total_size = ptVideoDevice->iHeight * ptVideoDevice->iWidth * 3;  // 总数据大小
    int packet_size = 4096;  // 单个数据包的大小
    int sent_bytes = 0;

    while (sent_bytes < total_size) {
        int bytes_to_send = total_size - sent_bytes;

        if(bytes_to_send > packet_size){  // 如果剩余的字节数大于packet_size，分块发送
            bytes_to_send = packet_size;
        }

        int bytes = sendto(this->sockfd, ptVideoDevice->rgb_data[ptVideoDevice->iVideoBufCurIndex] + sent_bytes, bytes_to_send, 0, (struct sockaddr *)&this->clientaddr, this->addrlen);
        if (bytes < 0) {
            Print_RED("发送数据失败, ptVideoDevice->iVideoBufCurIndex = %d",ptVideoDevice->iVideoBufCurIndex);
            break;
        }
        sent_bytes += bytes;
    }
#endif
}